package com.vichat.common.util;

import com.jcraft.jsch.*;
import com.vichat.common.vo.ftp.Ftp;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Properties;
import java.util.Vector;

public class SFtpUtil {

    private FTPChannel channel = null;


    public void connect(String ip,String user,String passwd){
        try {
            channel = new FTPChannel(ip, user, passwd);
        } catch (Exception e) {
            logger.error("connect失败", e);
        }
    }

    public void close(){

        try {
            if(channel!=null) {
                channel.channel.quit();
                channel.close();
            }
        } catch (Exception e) {
            logger.error("close失败", e);
        }
    }



    public  Vector list(String destPath) throws Exception {
        try {
            return channel.channel.ls(destPath);
        } catch (Exception e) {
            logger.error("list失败", e);
            return null;
        }
    }

    public  boolean mv(String sourcePath, String sourceFileName,String destPath, String destFileName) throws Exception {
        int retry = 1;
        int maxRerty = 3;
        boolean success = false;
        while(retry < maxRerty){
            try {
                StringBuilder src = new StringBuilder();
                if(StringUtils.isNotBlank(sourcePath)){
                    src.append(sourcePath);
                }
                src.append(sourceFileName);
                StringBuilder dest = new StringBuilder();
                if(StringUtils.isNotBlank(destPath)){
                    dest.append(destPath);
                }
                dest.append(destFileName);
                logger.info("mv "+src.toString() + " "+dest.toString());
                success = channel.rename(src.toString(),dest.toString());

            } catch (Exception e) {
                logger.error("mv失败,失败次数:"+retry, e);

            }
            if(success){
                return success;
            }else{
                retry++;
            }

        }
        return success;

    }


    public  SftpATTRS lstat(String remotePath) throws Exception {
        try {
            return channel.channel.lstat(remotePath);

        } catch (Exception e) {
            logger.error("lstat失败", e);
            return null;
        }
    }

    public  boolean chkdirs(String remotePath) throws Exception {
        try {
            if(lstat(remotePath) == null){//如果该目录不存在
                String[] dirs = StringUtils.split(remotePath,"/");
                StringBuilder path = new StringBuilder("/");
                for (String dir:dirs ) {
                    path.append(dir).append("/");
                    if(lstat(path.toString())==null){
                        mkdirs(path.toString());
                    }
                }
            }
            return true;
        } catch (Exception e) {
            logger.error("lstat失败", e);
            return false;
        }

    }


    public  void mkdirs(String remotePath) throws Exception {
        try {
            channel.channel.mkdir(remotePath);
        } catch (Exception e) {
            logger.error("mkdirs失败", e);
        }
    }


    public static void main(String[] args) throws Exception {
        SFtpUtil sFtpUtil = new SFtpUtil();
        sFtpUtil.connect("60.169.74.7","webuser","LyWv246");
//		Ftp ftp = new Ftp();
//		ftp.setIp("61.191.61.3");
//		ftp.setUsername("kkweb");
//		ftp.setPassword("hefei1949!@#$");
//		ftp.setRemotePath("/data/showfilepre/recd");
        sFtpUtil.chkdirs("/data/showfile/recd/2018/09");
        Vector list = sFtpUtil.list("/data/showfile/recd/2018/07/26");
        for (Object obj:list ) {
            ChannelSftp.LsEntry lsEntry = (ChannelSftp.LsEntry)obj;
            String fileName = lsEntry.getFilename();
            String longName=  lsEntry.getLongname();
            if(StringUtils.startsWith(longName,"-")){
                sFtpUtil.mv("/data/showfilepre/recd/",fileName,"/data/showfilepre/recd/temp/",fileName);
            }
            long fileSize = lsEntry.getAttrs().getSize();
            SftpATTRS sftpAttrs = lsEntry.getAttrs();
            sftpAttrs.isDir();
            System.out.println(lsEntry);
            System.out.println(lsEntry.getLongname());
        }
        sFtpUtil.close();


    }




    private static final transient Logger logger = LoggerFactory.getLogger(SFtpUtil.class);

    private static final int maxRetry = 3;

    public static Vector list(Ftp ftp, String destPath) throws Exception {
        FTPChannel channel = null;
        try {
            channel = new FTPChannel(ftp.getIp(), ftp.getUsername(), ftp.getPassword());
            //logger.info("ftp["+ftp.getIp()+"],username["+ftp.getUsername()+"],password["+ftp.getPassword()+"],destPath["+destPath+"]");
            return channel.channel.ls(destPath);
        } catch (Exception e) {
            logger.error("list失败", e);
            return null;
        }finally {
            if(channel!=null) {
                channel.channel.quit();
                channel.close();
            }
        }
    }

    public static boolean upload(Ftp ftp, File file) throws Exception {
        FTPChannel channel = null;
        try {
            channel = new FTPChannel(ftp.getIp(), ftp.getUsername(), ftp.getPassword());
            if (ftp.getRemotePath() != null) {
                channel.channel.cd(ftp.getRemotePath());
            }
            return channel.upload(file.getAbsolutePath(), file.getName());
        } catch (Exception e) {
            logger.error("upload失败", e);
            return false;
        }finally {
            if(channel!=null) {
                channel.channel.quit();
                channel.close();
            }
        }
    }

    public static boolean download(Ftp ftp, String localPath,String destPath, String fileName) throws Exception {
        FTPChannel channel = null;
        try {
            channel = new FTPChannel(ftp.getIp(), ftp.getUsername(), ftp.getPassword());
            if (ftp.getRemotePath() != null) {
                channel.channel.cd(ftp.getRemotePath());
            }
            return channel.download(localPath,destPath,fileName);
        } catch (Exception e) {
            logger.error("download失败", e);
            return false;
        }finally {
            if(channel!=null) {
                channel.channel.quit();
                channel.close();
            }
        }
    }

    public static boolean mv(Ftp ftp,String sourcePath, String sourceFileName,String destPath, String destFileName) throws Exception {
        int retry = 1;
        int maxRerty = 3;
        boolean success = false;
        while(retry < maxRerty){
            FTPChannel channel = null;
            try {
                channel = new FTPChannel(ftp.getIp(), ftp.getUsername(), ftp.getPassword());
                if (ftp.getRemotePath() != null) {
                    channel.channel.cd(ftp.getRemotePath());
                }
                StringBuilder src = new StringBuilder();
                if(StringUtils.isNotBlank(sourcePath)){
                    src.append(sourcePath);
                }
                src.append(sourceFileName);
                StringBuilder dest = new StringBuilder();
                if(StringUtils.isNotBlank(destPath)){
                    dest.append(destPath);
                }
                dest.append(destFileName);
                logger.info("mv "+src.toString() + " "+dest.toString());
                success = channel.rename(src.toString(),dest.toString());

            } catch (Exception e) {
                logger.error("mv失败,失败次数:"+retry, e);

            }finally {
                if(channel!=null) {
                    channel.channel.quit();
                    channel.close();
                }
            }
            if(success){
                return success;
            }else{
                retry++;
            }

        }
        return success;

    }

    public static void rm(Ftp ftp, String destPath, String destFileName) throws Exception {
        FTPChannel channel = null;
        try {
            channel = new FTPChannel(ftp.getIp(), ftp.getUsername(), ftp.getPassword());
            if (ftp.getRemotePath() != null) {
                channel.channel.cd(ftp.getRemotePath());
            }
            channel.channel.rm(destPath+destFileName);
        } catch (Exception e) {
            logger.error("mv失败", e);
        }finally {
            if(channel!=null) {
                channel.channel.quit();
                channel.close();
            }
        }
    }

    private static class FTPChannel {

        private Session session = null;
        public ChannelSftp channel = null;

        private static final Logger LOG = LoggerFactory.getLogger(FTPChannel.class.getName());

        public FTPChannel(String ftpHost,String username, String password) throws Exception {

            int ftpPort = 22;
            int timeout = 30000;

            JSch jsch = new JSch();

            session = jsch.getSession(username, ftpHost, ftpPort);
            if (session == null) {
                throw new Exception("session is null");
            }
            if (password != null) {
                session.setPassword(password);
            }
            Properties properties = new Properties();
            properties.put("StrictHostKeyChecking", "no");
            session.setConfig(properties);
            session.setTimeout(timeout);
            session.connect();

            channel = (ChannelSftp) session.openChannel("sftp");
            channel.connect();
            LOG.debug("Connected successfully to ftpHost=" + ftpHost + ", ftpUserName=" + username  + ", returning: " + channel);
        }

        public boolean upload(String src, String dest) {
            try {
                channel.put(src, dest);
            } catch (SftpException e) {
                e.printStackTrace();
                return false;
            }
            return true;
        }

        public boolean rename(String src, String dest) {
            try {
                channel.rename(src,dest);
            } catch (SftpException e) {
                e.printStackTrace();
                return false;
            }
            return true;
        }

        public boolean download(String src,String destPath, String fileName) {
            try {
                File file = new File(src + fileName);
                if(!file.getParentFile().exists()){
                    file.getParentFile().mkdirs();
                }
                channel.get(destPath + fileName,new FileOutputStream(file));
            } catch (SftpException e) {
                return false;
            } catch (FileNotFoundException e){
                return false;
            }
            return true;
        }

        public void close() throws Exception {
            channel.quit();

            if (channel != null) {
                channel.disconnect();
            }
            if (session != null) {
                session.disconnect();
            }
        }
    }
}
